
require 'redmine/ciphering'
require 'redmine/safe_attributes'

class Repository
  include Redmine::Ciphering
  include Redmine::SafeAttributes
    
  # Maximum length for repository identifiers
  IDENTIFIER_MAX_LENGTH = 255

  #has_many :changesets
  attr_accessor :changesets
  #has_many :filechanges
  attr_accessor :filechanges

  #serialize :extra_info
  attr_accessor :extra_info
  
  safe_attributes 'identifier',
    'login',
    'password',
    'path_encoding',
    'log_encoding',
    'is_default'

  safe_attributes 'url'

  def initialize (url, root_url=nil)
    @url = url
    @root_url = url
    @changesets = []
    @filechanges = []
  end
  
  # Removes leading and trailing whitespace
  def url=(arg)
    write_attribute(:url, arg ? arg.to_s.strip : nil)
  end
    
  # Removes leading and trailing whitespace
  def root_url=(arg)
    write_attribute(:root_url, arg ? arg.to_s.strip : nil)
  end

  def password
    read_ciphered_attribute(:password)
  end

  def password=(arg)
    write_ciphered_attribute(:password, arg)
  end
    
  def scm_adapter
    self.class.scm_adapter_class
  end

  def scm
    unless @scm
      @scm = self.scm_adapter.new(url, root_url
                                  #,login, password 
                                  #,path_encoding
                                  )
      if (root_url.nil? || root_url.empty?) && !(@scm.root_url.nil? || @scm.root_url.empty?)
        update_attribute(:root_url, @scm.root_url)
      end
    end
    @scm
  end
    
  def scm_name
    self.class.scm_name
  end

  def self.scm_adapter_class
    nil
  end
  
  def self.scm_command
    ret = ""
    begin
      ret = self.scm_adapter_class.client_command if self.scm_adapter_class
    rescue Exception => e
      #logger.error "scm: error during get command: #{e.message}"
    end
    ret
  end
  
  def self.scm_available
    ret = false
    begin
      ret = self.scm_adapter_class.client_available if self.scm_adapter_class
    rescue Exception => e
      #logger.error "scm: error during get scm available: #{e.message}"
    end
    ret
  end
  
        def logger
          self.class.logger
        end

        def self.logger
          Rails.logger
        end
        
  def merge_extra_info(arg)
    h = extra_info || {}
    return h if arg.nil?
    h.merge!(arg)
    #write_attribute(:extra_info, h)
    extra_info = h
  end

  def report_last_commit
    true
  end

  def supports_cat?
    scm.supports_cat?
  end

  def supports_annotate?
    scm.supports_annotate?
  end

  def supports_all_revisions?
    true
  end

  def supports_directory_revisions?
    false
  end

  def supports_revision_graph?
    false
  end

  def entry(path=nil, identifier=nil)
    scm.entry(path, identifier)
  end

  def entries(path=nil, identifier=nil)
    entries = scm.entries(path, identifier)
    load_entries_changesets(entries)
    entries
  end

  def branches
    scm.branches
  end

  def tags
    scm.tags
  end

  def default_branch
    nil
  end

  def properties(path, identifier=nil)
    scm.properties(path, identifier)
  end

  def cat(path, identifier=nil)
    scm.cat(path, identifier)
  end

  def diff(path, rev, rev_to)
    scm.diff(path, rev, rev_to)
  end

  def diff_format_revisions(cs, cs_to, sep=':')
    text = ""
    text << cs_to.format_identifier + sep if cs_to
    text << cs.format_identifier if cs
    text
  end

  # Returns a path relative to the url of the repository
  def relative_path(path)
    path
  end            
end